home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / tracker-4.13.lha / tracker / Arch / Hpux / low_audio.c < prev   
Encoding:
C/C++ Source or Header  |  1995-02-08  |  4.7 KB  |  215 lines

  1. /* hplow_audio.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* Driver for HP9000 series 710/7x5 with HP-UX 9.01 */
  6. /* Using low-level audio calls */
  7. /* Copyright 1993 Marc Espie   (Marc.Espie@ens.fr)  */
  8. /* Copyright 1993 Markus Gyger (mgyger@itr.ch) */
  9.  
  10. #include "defs.h"
  11. #include <fcntl.h>
  12. #include <unistd.h>
  13. #include <sys/audio.h>
  14. #include "extern.h"
  15.  
  16. ID("$Id: low_audio.c,v 1.1 1995/02/01 16:43:47 espie Exp $")
  17. #ifndef DEFAULT_SAMPLE_RATE
  18. #define DEFAULT_SAMPLE_RATE  22050
  19. #endif
  20.  
  21. #ifndef AUDIO_NAME
  22. #define AUDIO_NAME           "/dev/audio"
  23. #endif
  24. #ifndef AUDIO_CTL_NAME
  25. #define AUDIO_CTL_NAME       "/dev/audioCtl"
  26. #endif
  27.  
  28. LOCAL int audio;
  29. LOCAL int audio_ctl;
  30.  
  31. LOCAL struct audio_describe ainfo;
  32. LOCAL char *buffer;
  33. LOCAL short *sbuffer;
  34. LOCAL int index;
  35. LOCAL int sample_rate;
  36. LOCAL int channels;
  37. LOCAL int min_samples;
  38.  
  39. LOCAL int stereo;
  40. LOCAL int primary, secondary;
  41.  
  42. void set_mix(percent)
  43. int percent;
  44.     {
  45.     percent *= 256;
  46.     percent /= 100;
  47.     primary = percent;
  48.     secondary = 512 - percent;
  49.     }
  50.  
  51. LOCAL int available(f)
  52. int f;
  53.     {
  54.     int best = 0;
  55.     int i;
  56.  
  57.     for (i = 0; i < ainfo.nrates; i++)
  58.     if (abs(ainfo.sample_rate[i] - f) < abs(best - f))
  59.         best = ainfo.sample_rate[i];
  60.     return best;
  61.     }
  62.  
  63. int open_audio(f, s)
  64. int f;
  65. int s;
  66.     {
  67.     int type;
  68.  
  69.     audio_ctl = open(AUDIO_CTL_NAME, O_WRONLY | O_NDELAY);
  70.     if (audio_ctl == -1)
  71.         {
  72.         end_all("No audio control device");
  73.         }
  74.  
  75.     if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
  76.         {
  77.     end_all("No audio info");
  78.         }
  79.  
  80.     if (f == 0)
  81.         f = DEFAULT_SAMPLE_RATE;
  82.         /* round frequency to acceptable value */
  83.     sample_rate = available(f);
  84.  
  85.         /* check whether we have stereo device */
  86.     if (ainfo.nchannels < 2)
  87.         {
  88.             /* a 710 or 425 -> revert to base quality audio */
  89.         stereo = 0;
  90.         channels = 1;
  91.         }
  92.     else
  93.         {
  94.             /* 7x5 set up */
  95.         stereo = s;
  96.         if (stereo)
  97.             {
  98.             channels = 2;
  99.             set_mix(30);
  100.             }
  101.         else
  102.             channels = 1;
  103.         }
  104.  
  105.         /* write a minimum of samples to avoid underflows on 715 (???) */
  106.     switch (ainfo.audio_id)
  107.         {
  108.         case AUDIO_ID_CS4215:
  109.             /* empirically found values */
  110.             min_samples = 12288;
  111.             if (channels < 2) min_samples = 8192;
  112.             if (sample_rate <= 11025) min_samples = 6144;
  113.             if (sample_rate <= 8000) min_samples = 4096;
  114.             break;
  115.  
  116.         case AUDIO_ID_PSB2160:
  117.         default:
  118.             min_samples = 0;
  119.             break;
  120.         }
  121.  
  122.     if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT) == -1)
  123.         {
  124.           end_all("Linear format not available");
  125.         }
  126.     if (ioctl(audio_ctl, AUDIO_SET_CHANNELS, channels) == -1)
  127.         {
  128.           end_all("Could not set # of audio channels");
  129.         }
  130.     if (ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, sample_rate) == -1)
  131.         {
  132.           end_all("Could not set audio sample rate");
  133.         }
  134.  
  135.     audio = open(AUDIO_NAME, O_WRONLY | O_NDELAY);
  136.     if (audio == -1)
  137.         {
  138.           end_all("Could not open audio device");
  139.         }
  140.  
  141. #ifdef SET_OUTPUT
  142.         /* ensure we hear something */
  143.     if (ioctl(audio_ctl, AUDIO_SET_OUTPUT,
  144.         ((SET_OUTPUT & 1) ? AUDIO_OUT_INTERNAL : 0) |   /* speaker */
  145.         ((SET_OUTPUT & 2) ? AUDIO_OUT_EXTERNAL : 0) |   /* phones  */
  146.         ((SET_OUTPUT & 4) ? AUDIO_OUT_LINE : 0) |   /* line    */
  147.         ((SET_OUTPUT & 7) ? 0 : AUDIO_OUT_NONE)) == -1)
  148.           notice("Warning: could not set audio output");
  149. #endif
  150.  
  151.     index = 0;
  152.     sbuffer = (short *)malloc(2 * channels * sample_rate);
  153.     buffer = (char *)sbuffer;
  154.     if (!buffer)
  155.         end_all("Could not allocate buffer");
  156.     return sample_rate;
  157.     }
  158.  
  159. void set_synchro(s)
  160. int s;
  161.     {
  162.     }
  163.  
  164. int update_frequency()
  165.     {
  166.     int oldfreq;
  167.  
  168.     oldfreq = sample_rate;
  169.     if (ioctl(audio, AUDIO_GET_SAMPLE_RATE, &sample_rate) != -1)
  170.         {
  171.         if (oldfreq != sample_rate)
  172.             {
  173.             sbuffer = (short *)realloc(sbuffer, 2 * channels * sample_rate);
  174.             buffer = (char *)sbuffer;
  175.             return sample_rate;
  176.             }
  177.         }
  178.     return 0;
  179.     }
  180.  
  181. void output_samples(left, right)
  182. int left, right;
  183.     {
  184.     if (stereo)
  185.         {
  186.         sbuffer[index++] = (left * primary + right * secondary)/256;
  187.         sbuffer[index++] = (right * primary + left * secondary)/256;
  188.         }
  189.     else
  190.         sbuffer[index++] = left + right;
  191.     }
  192.  
  193. void flush_buffer()
  194.     {
  195.     if (index >= min_samples)
  196.         {
  197.         write(audio, buffer, 2 * index);
  198.         index = 0;
  199.         }
  200.     }
  201.  
  202. void discard_buffer()
  203.     {
  204.     if (ioctl(audio, AUDIO_RESET, RESET_TX_BUF) == -1)
  205.         notice("Warning: could not discard audio buffer");
  206.     }
  207.  
  208. void close_audio()
  209.     {
  210.     free(buffer);
  211.     close(audio);
  212.     close(audio_ctl);
  213.     }
  214.  
  215.